import json
import requests
from typing import Dict, List, Optional
from scripts.config_reader import ConfigReader
from scripts.import_data import SimpleDB


class RequestHandler:
    def __init__(self):
        config = ConfigReader().config
        self.base_url = config.get('api', 'base_url')
        self._session = requests.Session()

        # 安全解析headers
        headers = config.get('api', 'headers', fallback="{}")
        try:
            self._session.headers.update(json.loads(headers))
        except json.JSONDecodeError:
            self._session.headers.update({})

        self._session.verify = config.getboolean('api', 'verify_ssl')
        self._session.timeout = config.getint('api', 'timeout')
        self._test_results = {}  # 存储测试结果用于依赖

    def process_requests(self, case_ids: Optional[List[int]] = None,
                         filter_condition: Optional[Dict] = None):
        """执行测试用例

        Args:
            case_ids: 指定要执行的用例ID列表
            filter_condition: 筛选条件字典，如 {'method': 'post'}
        """
        with ConfigReader().get_cursor() as conn:
            for idx, row in enumerate(SimpleDB(conn).select('gdyh'), 1):
                if not (info := self._extract_request_info(row)):
                    continue

                # 用例筛选逻辑
                if case_ids and row[0] not in case_ids:  # 假设row[0]是用例ID
                    continue
                if filter_condition and not self._match_filter(info, filter_condition):
                    continue

                # 处理数据依赖
                info['data'] = self._resolve_dependencies(info['data'])

                if (result := self._send_request(**info)) and result['success']:
                    self._test_results[row[0]] = result['response']  # 存储结果
                    self._compare_response(result, info)

    def _extract_request_info(self, row):
        try:
            return {
                'case_id': row[0],  # 假设第0列是用例ID
                'url': self.base_url + row[4],
                'method': row[3].lower(),
                'data': row[5],
                'expected_output': row[6],
                'dependencies': row[7] if len(row) > 7 else None  # 依赖信息
            }
        except (IndexError, TypeError):
            return None

    def _send_request(self, url, method, data, **kwargs):
        try:
            response = getattr(self._session, method)(url, data=self._prepare_data(data))
            response.raise_for_status()
            return {
                'success': True,
                'status_code': response.status_code,
                'response': response.json() if response.text else None
            }
        except requests.exceptions.RequestException as e:
            print(f"请求失败: {e}")
            return None

    def _compare_response(self, result, info):
        try:
            expected = self._parse_expected_output(info['expected_output'])
            if result['response'] != expected:
                print(f"\n用例 {info['case_id']} 结果不匹配 [Status: {result['status_code']}]")
                print(f"URL: {info['url']}")
                print(f"预期: {expected}")
                print(f"实际: {result['response']}")
                print("-" * 50)
        except Exception as e:
            print(f"比较结果时出错: {e}")

    def _parse_expected_output(self, expected):
        """解析预期输出"""
        if isinstance(expected, str):
            try:
                return json.loads(expected)
            except json.JSONDecodeError:
                return expected
        return expected

    def _match_filter(self, info, filter_condition):
        """检查用例是否匹配筛选条件"""
        for key, value in filter_condition.items():
            if info.get(key) != value:
                return False
        return True

    def _resolve_dependencies(self, data):
        """解析数据依赖"""
        if not data or not isinstance(data, str):
            return data

        try:
            # 简单实现: 替换${case_id}为实际结果
            for case_id, result in self._test_results.items():
                placeholder = f"${{{case_id}}}"
                if placeholder in data:
                    if isinstance(result, (dict, list)):
                        data = data.replace(placeholder, json.dumps(result))
                    else:
                        data = data.replace(placeholder, str(result))
            return json.loads(data) if data.startswith('{') else data
        except Exception:
            return data

    def _prepare_data(self, data):
        """准备请求数据"""
        if isinstance(data, str):
            try:
                return json.loads(data)
            except json.JSONDecodeError:
                return data
        return data


if __name__ == '__main__':
    handler = RequestHandler()

    # 使用示例:
    # 1. 执行所有用例
    #handler.process_requests()

    # 2. 执行指定ID的用例
    handler.process_requests(case_ids=[1, 3, 5])

    # 3. 按条件筛选用例
    #handler.process_requests(filter_condition={'method': 'post'})